package com.zankong.tool.zkapp.v8fn.socket_pck;

import android.content.Intent;

import com.eclipsesource.v8.V8Function;
import com.eclipsesource.v8.V8Object;
import com.zankong.tool.zkapp.ZKToolApi;
import com.zankong.tool.zkapp.util.Util;
import com.zankong.tool.zkapp.util.V8Utils;
import com.zankong.tool.zkapp.util.ZKAppV8;
import com.zankong.tool.zkapp.zk_interface.ZKV8Fn;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONObject;

import java.util.ArrayList;

/**
 * Created by YF on 2018/6/29.
 */

@ZKAppV8
public class ZKSocket implements ZKV8Fn {
    private V8Object v8Socket;
    private V8Function v8io;
    private ArrayList<SocketObj> events;
    private Boolean isComplete = false;

    public ZKSocket() {
        v8Socket = new V8Object(ZKToolApi.runtime);
        events = new ArrayList<>();
        EventBus.getDefault().register(this);
    }

    @Override
    public void addV8Fn() {
        v8Socket.registerJavaMethod((receiver, parameters) -> {
            String event = parameters.getString(0);
            V8Function callBack = (V8Function) parameters.getObject(1);
            SocketObj obj = new SocketObj.Builder().addMethod("on").addEvent(event).addCallBack(args -> ZKToolApi.getInstance().getJsHandler().post(() -> {
                if (args.length > 0) {
                    if (args[0] instanceof String) {
                        Util.log("socket","args:string");
                        callBack.call(null, args);
                        Util.log("socket",args[0]+":args:string end");
                    } else if (args[0] instanceof JSONObject) {
                        Util.log("socket","args:JSONObject");
                        args[0] = V8Utils.parse(args[0].toString());
                        callBack.call(null, args);
                    }else {
                        Util.log("socket","args:other");
                    }
                }
            })).build();
            if (isComplete){
                EventBus.getDefault().post(obj);
            }else {
                events.add(obj);
            }
            return null;
        },"on");
        v8Socket.registerJavaMethod((receiver, parameters) -> {
            String event = parameters.getString(0);
            Object param = parameters.get(1);
            SocketObj obj = new SocketObj.Builder().addMethod("emit").addObjects(param).addEvent(event).addCallBack(args -> ZKToolApi.getInstance().getJsHandler().post(() -> {
                if (parameters.length() >= 3) {
                    if (args.length > 0) {
                        if (args[0] instanceof String) {
                            ((V8Function) parameters.getObject(2)).call(null, args[0]);
                        } else if (args[0] instanceof JSONObject) {
                            ((V8Function) parameters.getObject(2)).call(null, V8Utils.parse(args[0].toString()));
                        }
                    }
                }

            })).build();
            events.add(obj);
            if (isComplete){
                EventBus.getDefault().post(obj);
            }
            return null;
        },"emit");
        v8Socket.registerJavaMethod((receiver, parameters) -> {
            SocketObj connect = new SocketObj.Builder().addMethod("connect").build();
            events.add(connect);
            if (isComplete){
                EventBus.getDefault().post(connect);
            }
            return null;
        },"connect");
        v8Socket.registerJavaMethod((receiver, parameters) -> {
            SocketObj disconnect = new SocketObj.Builder().addMethod("disconnect").build();
            events.add(disconnect);
            if (isComplete) {
                EventBus.getDefault().post(disconnect);
            }
            return null;
        },"disconnect");
        v8Socket.registerJavaMethod((receiver, parameters) -> {
            SocketObj off = new SocketObj.Builder().addMethod("off").build();
            events.add(off);
            if (isComplete) {
                EventBus.getDefault().post(off);
            }
            return null;
        },"off");
        v8io = new V8Function(ZKToolApi.runtime, (receiver, parameters) -> {
            String url = parameters.getString(0);
            Intent intent = new Intent(ZKToolApi.getInstance().getContext(), ZKServiceSocket.class);
            intent.putExtra("url",url);
            ZKToolApi.getInstance().getContext().startService(intent);
            return V8Utils.createFrom(v8Socket);
        });
        ZKToolApi.runtime.add("io",v8io);
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onMessageEvent(String s) {
        if ("complete".equals(s)){
            isComplete = true;
            for (SocketObj event : events) {
                EventBus.getDefault().post(event);
            }
        }
    };

}
